package org.example.cicdi.service.impl.third.fieldcondition;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.example.cicdi.enums.EnumWhiteColumnAnnotation;
import org.example.cicdi.service.impl.second.FieldAnnotationServiceSecond;
import org.example.codegenerate.modelext.WebVo.Enum.EnumJavaMappingDbType;
import org.example.codegenerate.modelext.WebVo.domian.column.ColumnVoDomain;
import org.example.codegenerate.modelext.WebVo.domian.column.DbVo;
import org.example.codegenerate.modelext.WebVo.domian.table.WebModelVo;


import javax.persistence.Column;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import java.lang.reflect.Field;
import java.util.List;

@Data
@Slf4j
public abstract class AbstractColumnAndManyToOne implements FieldAnnotationServiceSecond {
    protected FieldCondition localfieldCondition=new FieldCondition();

    @Override
    public String getCode() {
        return EnumWhiteColumnAnnotation.Column.getCode();
    }

    @Override
    public ColumnVoDomain handleFieldVo(Field field, ColumnVoDomain column, WebModelVo webModelVo, List<WebModelVo> webModelVoList){
        FieldCondition outfieldcondition=new FieldCondition();
        if(field.getAnnotation(Column.class)!=null)
            outfieldcondition.setHasorNotColumn(EnumConsantExistFieldType.HasColumn.getStatus());
        else
            outfieldcondition.setHasorNotColumn(EnumConsantExistFieldType.NoColumn.getStatus());
        if(field.getAnnotation(ManyToOne.class)!=null) {
            outfieldcondition.setHasorNotJpaManyToOne(EnumConsantExistFieldType.HasManyToOne.getStatus());
        } else
            outfieldcondition.setHasorNotJpaManyToOne(EnumConsantExistFieldType.NoManyToOne.getStatus());
        if(field.getAnnotation(JoinColumn.class)!=null) {
            outfieldcondition.setHasorNotJoinColumn(EnumConsantExistFieldType.HasJoinColumn.getStatus());
        } else
            outfieldcondition.setHasorNotJoinColumn(EnumConsantExistFieldType.NoJoinColumn.getStatus());
        if(localfieldCondition.equals(outfieldcondition)){
            log.info("当前正在处理的字段是:{},column注解:{},ManyToOne注解:{},joinColumn注解:{}",field.getName(),localfieldCondition.getHasorNotColumn(),localfieldCondition.getHasorNotJpaManyToOne(),localfieldCondition.getHasorNotJoinColumn());
            execute(field,column,webModelVo,webModelVoList);
            log.info("当前已经处理完成的字段是:{}",field.getName());
        }
        return column;
    }

    protected abstract void execute(Field field, ColumnVoDomain column, WebModelVo webModelVo, List<WebModelVo> webModelVoList);




    protected void setFieldDbTypeExt(Field field, Column vo, DbVo db) {
        //如果columnDefinition，不是采用默认值。因为默认值就是""，如果写错了，JPA在实例化的时候，就提示了
        EnumJavaMappingDbType enumJavaMappingDbType;
        if (vo != null) {
            if (vo.columnDefinition() != null) {
                if (!vo.columnDefinition().equalsIgnoreCase("")) {
                    enumJavaMappingDbType = EnumJavaMappingDbType.getBycolumnDefinition(vo.columnDefinition());
                    //assert 布尔表达式 ：“错误信息提示”；
                    assert enumJavaMappingDbType != null : "Column注解中字段的类型不在系统的支持范围之内，当前系统仅支持8种类型,varchar,text,blob,date,datetime,decimal,int,double";
                    //log.info("当前正常处理的字段类型：{}，字段的名称为{}",enumJavaMappingDbType,field.getName(),enumJavaMappingDbType.getDbname());
			/*//先特殊处理一下，针对DateTime的，全部转为Date
			if(enumJavaMappingDbType.getDbname().equalsIgnoreCase("datetime")){
				db.setDbType("date");
			}*/
                } else {
                    //如果有Column，但是在这个上面没有columnDefinition，那么就采用默认的字段类型。但是字段类型必须在6种之内，String，Date，Decimal，Integer，Double
                    enumJavaMappingDbType = EnumJavaMappingDbType.getByDbJavaTypeName(field.getType().getSimpleName());
                    assert enumJavaMappingDbType != null : "Java中定义的字段的类型不在系统的支持范围之内，当前系统仅支持6种Java类型,String," +
                            "Date,BigDecimal,Integer,Double";
                }

                db.setDbType(enumJavaMappingDbType.getCurrentFrameWorkNeededDbType());
            }
        }
    }
    protected abstract void setFieldDbTypeExt(Field field,  DbVo db) ;




}
